home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / dskut / activate.zip / ACTIVATE.C < prev    next >
C/C++ Source or Header  |  1992-12-04  |  9KB  |  318 lines

  1.  
  2. /*
  3.  *  Activate.c (v1.01)
  4.  *
  5.  *  Utility for setting the Active partition on a HD.
  6.  *
  7.  *  Author: Ronan Mullally October 1992.
  8.  *          < H235_003@ccvax.ucd.ie >
  9.  *          < ronan@bermuda.ucd.ie >
  10.  *          < ronan.mullally@f151.n263.z2.fidonet.org >
  11.  *
  12.  *  Usage: Activate [-d] [-l] [partition #]
  13.  *
  14.  *         -d: Deactivate given partition #
  15.  *         -l: List partition Table(s)
  16.  *         # : Number of partition to (De)Activate
  17.  *
  18.  *         if no command line params are given -l is assumed
  19.  *
  20.  *
  21.  *  Notes: I make *no* guarentees that this program is 100% safe - All
  22.  *         I'll say is that it hasn't damaged my own Hard Disk (yet!)
  23.  *
  24.  *         Most of the code should be fairly portable - the only exceptions
  25.  *         are the functions contained in the DOS-ACT.c and NDOS-ACT.c files.
  26.  *         which contain the routines for reading and writing the 1st sector
  27.  *         of the hard drive.
  28.  *
  29.  */
  30.  
  31. #include "activate.h"
  32. #include "config.h"               /* Set any system dependant stuff here */
  33.  
  34.  
  35. static systypes SystemTypes[NUMBER_OF_SYSTEM_TYPES] =
  36. {
  37.   { 0x00, "Empty" },                              /* Most of these were  */
  38.   { 0x01, "DOS 12-bit FAT" },                     /* 'plagerised' from   */
  39.   { 0x02, "XENIX root" },                         /* the fdisk program   */
  40.   { 0x03, "XENIX user" },                         /* provided with Linux */
  41.   { 0x04, "DOS 16-bit FAT, < 32MB" },
  42.   { 0x05, "DOS Extended" },
  43.   { 0x06, "DOS 16-bit FAT, >= 32MB" },
  44.   { 0x07, "OS/2 HPFS" },
  45.   { 0x08, "AIX" },
  46.   { 0x09, "AIX bootable / Coherent" },
  47.   { 0x0A, "OPUS" },
  48.   { 0x40, "Venix" },
  49.   { 0x51, "Ontrack extended partition" },
  50.   { 0x52, "Microport" },
  51.   { 0x63, "GNU HURD" },
  52.   { 0x64, "Novell" },
  53.   { 0x75, "PC/IX" },
  54.   { 0x80, "Old MINIX" },
  55.   { 0x81, "Linux / MINIX" },
  56.   { 0x82, "Linux swap" },
  57.   { 0x83, "Linux extended fs" },
  58.   { 0x93, "Amiga" },
  59.   { 0x94, "Amiga BBT" },
  60.   { 0xB7, "BSDI" },
  61.   { 0xB8, "Syrinx" },
  62.   { 0xDB, "CP/M" },
  63.   { 0xE1, "DOS access" },
  64.   { 0xE3, "DOS R/O" },
  65.   { 0xF2, "DOS secondary" },
  66.   { 0xFF, "BBT" },
  67.   { 0x00, "Unknown" }                  /* Displayed if system ID unknown */
  68. };
  69.  
  70. int display = 0, activate = 0, deactivate = 0;
  71. byte buffer[512];                       /* Store Master Boot Sector here */
  72.  
  73.  
  74. /*
  75.  * Calculates the Start and End boundaries for the given partn table entry.
  76.  * The 2 high-order bits of the Cylinder are stored in the 2 high order bits
  77.  * of start_sector / end_sector, this these sector values are only 6 bits
  78.  *
  79.  */
  80.  
  81. void get_partition_boundaries(entry, Start, End)
  82. partition_table_entry entry;
  83. location *Start;
  84. location *End;
  85. {
  86.   Start->Side = entry.start_sector_head;
  87.   Start->Sector = entry.start_sector & 0x3F;   /* 2 high bits are for cyl */
  88.   Start->Cylinder = ((entry.start_sector & 0xC0) << 2)+(entry.start_cylinder);
  89.  
  90.   End->Side = entry.end_sector_head;
  91.   End->Sector = entry.end_sector & 0x3F;
  92.   End->Cylinder = ((entry.end_sector & 0xC0) << 2) + (entry.end_cylinder);
  93. }
  94.  
  95.  
  96. /*
  97.  * Returns index into the SystemTypes array where the Description of the
  98.  * given ID byte can be found.  If no match is found the index of the last
  99.  * entry is given - this corresponds to the description "Unknown".
  100.  *
  101.  */
  102.  
  103. int get_system_type(system_ID)
  104. byte system_ID;
  105. {
  106.   int x;
  107.  
  108.   for(x = 0; x < NUMBER_OF_SYSTEM_TYPES; x++)    /* Search for known ID */
  109.     if(SystemTypes[x].ID == system_ID)           /* if a match is found */
  110.       return(x);                                 /* return desc's index */
  111.  
  112.   return(NUMBER_OF_SYSTEM_TYPES);                /* return unknown index */
  113. }
  114.  
  115.  
  116. /*
  117.  *  Displays Partition Table data
  118.  *
  119.  */
  120.  
  121. void show_partition_table(partn, drive)
  122. partition_table partn;
  123. int drive;
  124. {
  125.   int x;
  126.   location Start, End;
  127.  
  128. #ifdef __MSDOS__
  129.   printf("\nPartition Table for Hard Drive %d:", drive);
  130. #else
  131.   printf("\nPartition Table for Hard Drive %s:", drive_name[drive]);
  132. #endif
  133.  
  134.   printf("\n\t\t\t\t\t\t    Starting       Ending");
  135.   printf("\nActive\t\tSystem Type\t    Size (KB)    Side Cyl Sect  Side Cyl Sect\n");
  136.   for(x = 0; x < 4; x++)
  137.   {
  138.     get_partition_boundaries(partn.entry[x], &Start, &End);
  139.     printf("  %-3s", partn.entry[x].boot_flag ? "Yes" : "No");
  140.     printf("\t%-30s", SystemTypes[get_system_type(partn.entry[x].ID)].Desc);
  141.     printf("%6ld", partn.entry[x].sectors_in_partn / 2);
  142.     printf("%8d %4d %3d", Start.Side, Start.Cylinder, Start.Sector);
  143.     printf("%6d %4d %3d\n", End.Side, End.Cylinder, End.Sector);
  144.   }
  145. }
  146.  
  147.  
  148. /*
  149.  * Makes the given partition the booting partition - done simply by setting
  150.  * the boot_flag = 0x80.
  151.  *
  152.  */
  153.  
  154. void activate_partition(partition)
  155. partition_table_entry *partition;
  156. {
  157.    partition->boot_flag = 0x80;
  158. }
  159.  
  160.  
  161. /*
  162.  * Resets the given partition's boot_flag, thus making it inactive
  163.  *
  164.  */
  165.  
  166. void deactivate_partition(partition)
  167. partition_table_entry *partition;
  168. {
  169.   partition->boot_flag = 0x00;
  170. }
  171.  
  172.  
  173. /*
  174.  *  Displays an error message and gives Usage information
  175.  *
  176.  */
  177.  
  178. void Usage(message, path, errorlevel)
  179. char *message;
  180. char *path;
  181. int errorlevel;
  182. {
  183.   printf("\nActivate v1.01 Hard Disk Partition selector (Ronan Mullally, 1992)\n");
  184.   if(message != "") printf("\n%s", message);
  185.  
  186.   printf("\n\n%cUsage:  %s [-d] [-l] [partition #]\n", 7, path);
  187.   printf("\t-d\t   : Deactivate given partition\n");
  188.   printf("\t-l\t   : Display Partition Table(s)\n");
  189.   printf("\tpartition #: Number of Partition to activate\n\n");
  190.   printf(" Eg: %s 1     Activates 1st partition on Drive 0\n", path);
  191.   printf("     %s -d 6  Deactivates 2nd partition on Drive 1\n\n", path);
  192.  
  193.   exit(errorlevel);
  194. }
  195.  
  196.  
  197. /*
  198.  * Checks the command line for invalid parameters, processes valid options
  199.  * and extracts a partition number (if given).
  200.  *
  201.  * Returns partition number given on command line, or aborts if invalid
  202.  * options were given
  203.  *
  204.  */
  205.  
  206. int check_command_line(argc, argv)
  207. int argc;
  208. char *argv[];
  209. {
  210.   int x, y = 0, partition_number = 0, error = 0;
  211.   char *buffer[40];
  212.  
  213.   for(x = 1; x < argc && !error; x++)
  214.   {
  215.     for(y = 0; !error && argv[x][y] != '\0'; y++)
  216.       if(!isdigit(argv[x][y]))
  217.         error = 1;
  218.  
  219.     if(!error)
  220.     {
  221.       partition_number = atoi(argv[x]);
  222.       activate = !deactivate;
  223.     }
  224.     else if(!strcmp(argv[x], "-l"))
  225.     {
  226.       display = 1;
  227.       error = 0;
  228.       continue;
  229.     }
  230.     else if(!strcmp(argv[x], "-d"))
  231.     {
  232.       deactivate = 1;
  233.       activate = 0;
  234.       error = 0;
  235.       continue;
  236.     }
  237.     else
  238.     {
  239.       error = 1;
  240.       break;
  241.     }
  242.   }
  243.  
  244.   if(error)
  245.   {
  246.     sprintf((char *) buffer, "Invalid command line argument: %s", argv[x]);
  247.     Usage((char*) buffer, argv[0], BAD_COMMAND_LINE);
  248.   }
  249.   return(partition_number);
  250. }
  251.  
  252.  
  253.  
  254.  
  255.  
  256. int main(argc, argv)
  257. int argc;
  258. char *argv[];
  259. {
  260. #ifdef __MSDOS__
  261.   int drive = 0x80;          /* for DOS drives are referenced as numbers */
  262. #else
  263.   char *drive;                            /* for *nix they are filenames */
  264. #endif
  265.  
  266.   int max_partition, partition_to_activate = 0, x, y, drive_count;
  267.   partition_table partn;
  268.  
  269.   if(argc > 4)
  270.     Usage("Too many parameters on command line", argv[0], BAD_COMMAND_LINE);
  271.  
  272.   else if(argc == 1) display = 1;         /* no options given, just list */
  273.  
  274.   else partition_to_activate = check_command_line(argc, argv);
  275.  
  276.   drive_count = determine_number_of_drives();
  277.   max_partition = drive_count * 4;                 /* 4 partns per drive */
  278.  
  279.   if(display)
  280.     printf("\n\n%d Hard Drive%s found", drive_count, drive_count > 1 ? "s" : "");
  281.  
  282.   if((!partition_to_activate && !display) || (partition_to_activate > max_partition))
  283.     Usage("Invalid partition number", argv[0], BAD_PARTITION_NUMBER);
  284.  
  285.   for(x = 0; x < drive_count; x++)
  286.   {
  287. #ifdef __MSDOS__
  288.     drive += x;
  289. #else
  290.     drive = drive_name[x];
  291. #endif
  292.  
  293.     read_partition_table(&partn, drive);
  294.  
  295.     if((partition_to_activate-1) / 4 == x)  /* partition on this drive ? */
  296.     {
  297.       if(activate)                           /* Activate given partition */
  298.       {
  299.         for(y = 0; y < 4; y++)
  300.